package com.chinatechstar.file.service.impl;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.*;

import com.chinatechstar.admin.entity.SysUser;
import com.chinatechstar.admin.mapper.SysUserMapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ResourceUtils;
import org.springframework.web.multipart.MultipartFile;

import com.chinatechstar.account.controller.SysUserDetailController;
import com.chinatechstar.admin.controller.SysRoleController;
import com.chinatechstar.component.commons.result.PaginationBuilder;
import com.chinatechstar.component.commons.utils.CollectionUtils;
import com.chinatechstar.component.commons.utils.CurrentUserUtils;
import com.chinatechstar.component.commons.utils.SequenceGenerator;
import com.chinatechstar.file.mapper.FileMapper;
import com.chinatechstar.file.service.FileService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

/**
 * 文件信息的业务逻辑实现层
 *
 */
@Service
@Transactional
public class FileServiceImpl implements FileService {

    private final Logger logger = LoggerFactory.getLogger(getClass());
    private static SequenceGenerator sequenceGenerator = new SequenceGenerator();

    @Autowired
    private SysUserDetailController sysUserDetailServiceClient;
    @Autowired
    private SysRoleController sysRoleServiceClient;
    @Autowired
    private FileMapper fileMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 查询文件分页
     */
    @Override
    public Map<String, Object> queryFile(Integer currentPage, Integer pageSize, String originalFilename, String sorter) {
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("originalFilename", originalFilename);
        paramMap.put("tenantCode", CurrentUserUtils.getOAuth2AuthenticationInfo().get("tenantCode"));// 当前用户的租户编码
        if (StringUtils.isNotBlank(sorter)) {
            String sort = sorter.substring(0, sorter.lastIndexOf('_'));
            String sequence = "ascend".equals(sorter.substring(sorter.lastIndexOf('_') + 1)) ? "ASC" : "DESC";
            paramMap.put("sort", sort);
            paramMap.put("sequence", sequence);
        } else {
            paramMap.put("sort", "createTime");
            paramMap.put("sequence", "DESC");
        }
        Page<Object> page = PageHelper.startPage(currentPage, pageSize);
        List<LinkedHashMap<String, Object>> resultList = fileMapper.queryFile(paramMap);

        String roleData = sysRoleServiceClient.queryRoleData("uploaddownload", CurrentUserUtils.getOAuth2AuthenticationInfo().get("name"));
        String[] roleDataArray = roleData == null ? null : roleData.split(",");
        if (roleDataArray != null && roleDataArray.length > 0) {// 处理数据权限
            return PaginationBuilder.buildResult(CollectionUtils.convertFilterList(resultList, roleDataArray), page.getTotal(), currentPage, pageSize);
        } else {
            return PaginationBuilder.buildResult(resultList, page.getTotal(), currentPage, pageSize);
        }
    }

    /**
     * 删除文件
     */
    @Override
    public void deleteFile(Long[] id) throws IOException {
        List<String> urlList = fileMapper.queryUrlList(id);
        File rootDirectoryPath = new File(ResourceUtils.getURL("classpath:").getPath());
        for (int i = 0; i < urlList.size(); i++) {
            String path = rootDirectoryPath + urlList.get(i);
            Files.deleteIfExists(Paths.get(path));// 删除磁盘里的文件
        }
        fileMapper.deleteFile(id); // 删除数据库文件记录
    }

    /**
     * 上传文件
     */
    @Override
    public void uploadFile(MultipartFile file, Long id, String uploadType) throws IOException {
        String fileName = DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS")
                + Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf('.'), file.getOriginalFilename().length());
        String path = generatePath(fileName);

        Files.write(Paths.get(path).normalize().toAbsolutePath(), file.getBytes(), StandardOpenOption.CREATE_NEW);

        if ("avatar".equals(uploadType)) {
            sysUserDetailServiceClient.updateAvatar("/api/file/static/upload/" + fileName, id);
        }

        com.chinatechstar.file.entity.File entity = new com.chinatechstar.file.entity.File();
        entity.setName(file.getName());
        entity.setOriginalFilename(file.getOriginalFilename());
        entity.setFileSize(file.getSize());
        entity.setContentType(file.getContentType());
        entity.setUrl("/static/upload/" + fileName);
        entity.setId(sequenceGenerator.nextId());
        entity.setTenantCode(CurrentUserUtils.getOAuth2AuthenticationInfo().get("tenantCode"));// 当前用户的租户编码
        fileMapper.insertFileSysUser(sequenceGenerator.nextId(), entity.getId(), id);
        fileMapper.insertFile(entity);

        logger.info("此文件已上传： {}", file.getOriginalFilename());
    }

    /**
     * 上传文件
     */
    @Override
    public com.chinatechstar.file.entity.File uploadFile(MultipartFile file) throws IOException {
        String fileName = DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS")
                + Objects.requireNonNull(file.getOriginalFilename()).substring(file.getOriginalFilename().lastIndexOf('.'), file.getOriginalFilename().length());
        String path = generatePath(fileName);

        Files.write(Paths.get(path).normalize().toAbsolutePath(), file.getBytes(), StandardOpenOption.CREATE_NEW);

        SysUser sysUser = sysUserMapper.getUserByUsername(CurrentUserUtils.getOAuth2AuthenticationInfo().get("name"));

        com.chinatechstar.file.entity.File entity = new com.chinatechstar.file.entity.File();
        entity.setName(file.getName());
        entity.setOriginalFilename(file.getOriginalFilename());
        entity.setFileSize(file.getSize());
        entity.setContentType(file.getContentType());
        entity.setUrl("/static/upload/" + fileName);
        entity.setId(sequenceGenerator.nextId());
        entity.setTenantCode(CurrentUserUtils.getOAuth2AuthenticationInfo().get("tenantCode"));// 当前用户的租户编码
        fileMapper.insertFileSysUser(sequenceGenerator.nextId(), entity.getId(), sysUser.getId());
        fileMapper.insertFile(entity);

        logger.info("此文件已上传： {}", file.getOriginalFilename());
        return entity;
    }

    /**
     * 上传文件到与jar包同级的外部目录
     *
     * @param fileName 已修改成时间戳的文件名称
     * @return
     * @throws IOException
     */
    public String generatePath(String fileName) throws IOException {
        File rootDirectoryPath = new File(ResourceUtils.getURL("classpath:").getPath());
        if (!rootDirectoryPath.exists()) {
            rootDirectoryPath = new File("");
        }
        File uploadPath = new File(rootDirectoryPath.getAbsolutePath(), "static/upload/");
        if (!uploadPath.exists()) {
            uploadPath.mkdirs();
        }
        return rootDirectoryPath.getAbsolutePath() + "/static/upload/" + fileName;
    }

}
